﻿using System;
using System.Collections.Generic;
using System.Runtime.Serialization;
using MugenMvvmToolkit.Interfaces;
using MugenMvvmToolkit.Utils;

namespace MugenMvvmToolkit.Models
{
    /// <summary>
    ///     Represents the validation context.
    /// </summary>
#if WPF
    [Serializable]
#endif
    [DataContract]
    public class ValidatorContext : IValidatorContext
    {
        #region Constructors

        /// <summary>
        ///     Initializes a new instance of the <see cref="ValidatorContext" /> class.
        /// </summary>
        public ValidatorContext(object instanceToValidate, IServiceProvider serviceProvider = null)
            : this(instanceToValidate, null, null, null, serviceProvider)
        {
        }

        /// <summary>
        ///     Initializes a new instance of the <see cref="ValidatorContext" /> class.
        /// </summary>
        public ValidatorContext(object instanceToValidate, IDictionary<string, ICollection<string>> errorNameMapping,
                                IList<string> ignoredProperties, IServiceProvider serviceProvider = null)
            : this(instanceToValidate, errorNameMapping, ignoredProperties, null, serviceProvider)
        {
        }

        /// <summary>
        ///     Initializes a new instance of the <see cref="ValidatorContext" /> class.
        /// </summary>
        public ValidatorContext(object instanceToValidate, IDictionary<string, ICollection<string>> errorNameMapping,
                                ICollection<string> ignoredProperties, IDictionary<object, object> validationMetadata,
                                IServiceProvider serviceProvider = null)
        {
            Should.NotBeNull(instanceToValidate, "instanceToValidate");
            InstanceToValidate = instanceToValidate;
            PropertiesMapping = errorNameMapping ?? new Dictionary<string, ICollection<string>>();
            IgnoreProperties = ignoredProperties ?? new HashSet<string>();
            ValidationMetadata = validationMetadata ?? new Dictionary<object, object>();
            ServiceProvider = serviceProvider;
        }

        #endregion

        #region Implementation of IValidatorContext

        /// <summary>
        ///     Gets the object to validate.
        /// </summary>
        public object InstanceToValidate { get; private set; }

        /// <summary>
        ///     Gets or sets the validation metadata.
        /// </summary>
        public IDictionary<object, object> ValidationMetadata { get; private set; }

        /// <summary>
        ///     Gets the error properties mapping.
        /// </summary>
        public IDictionary<string, ICollection<string>> PropertiesMapping { get; private set; }

        /// <summary>
        ///     Gets the list of properties that will not be validated.
        /// </summary>
        public ICollection<string> IgnoreProperties { get; private set; }

        /// <summary>
        ///     Gets the service provider.
        /// </summary>
        public IServiceProvider ServiceProvider { get; private set; }

        #endregion

        #region Implementation of IServiceProvider

        /// <summary>
        /// Gets the service object of the specified type.
        /// </summary>
        /// <returns>
        /// A service object of type <paramref name="serviceType"/>.-or- null if there is no service object of type <paramref name="serviceType"/>.
        /// </returns>
        /// <param name="serviceType">An object that specifies the type of service object to get. </param>
        object IServiceProvider.GetService(Type serviceType)
        {
            Should.PropertyBeNotNull(ServiceProvider, "ServiceProvider");
            return ServiceProvider.GetService(serviceType);
        }

        #endregion
    }
}